package com.mach.platform.service;

import com.google.common.collect.Lists;
import com.mach.platform.domain.Order;
import com.mach.platform.domain.OrderFile;
import com.mach.platform.repository.OrderFileRepo;
import com.mach.platform.utils.FileUtil;
import com.mach.platform.utils.Office2PDF;
import com.mach.platform.utils.springdata.DynamicSpecifications;
import com.mach.platform.utils.springdata.SearchFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.*;
import java.util.List;
import java.util.Map;

@Service
public class OrderFileServiceImpl implements BaseService<OrderFile> {

    //操作条件管理(正式)
    private static final String OPERATION_CONDITION_FORMAL = "operationConditionFormal";
    //操作条件管理(非正式)
    private static final String OPERATION_CONDITION_NOT_FORMAL = "operationConditionNotFormal";
    //工作规范管理
    private static final String WORK_STANDARD = "workStandard";
    //生产配置
    private static final String PRODUCTION_CONFIGURATION = "productionConfiguration";
    //岗位配置
    private static final String POST_ALLOCATION = "postAllocation";

    private static final String PATH_NO_EXIST = "目录不存在";
    private static final String FILE_NO_EXIST = "文件不存在";

    //win
//    public static String spacer= "\\";
    //linux
    public static String spacer= "/";

    @Autowired
    private OrderFileRepo orderFileRepo;
    @Override
    public OrderFile save(OrderFile orderFile) {
        return null;
    }

    @Override
    public List<OrderFile> insertObjInBatch(List<OrderFile> list) {
        return null;
    }

    @Override
    public OrderFile update(OrderFile orderFile) {
        return null;
    }

    @Override
    public int delete(Long[] ids) {
        return 0;
    }

    @Override
    public Page<OrderFile> list(Pageable pageable, Map params) {
        if (params != null && params.size() > 0) {
            String keyword = params.get("keyword").toString().trim();
            String dir = params.get("dir").toString().trim();
            if (keyword != null && keyword != "") {
                params.put("fileName_plike", keyword);
            }
            if (dir != null && dir != "") {
                params.put("dir_eq", dir);
            }
            params.remove("keyword");
            params.remove("dir");
        }
        params.put("fileName_nn", "fileNameNotNull");
        params.put("dir_nn", "dirNotNull");
        Specification specification = DynamicSpecifications.bySearchFilter(SearchFilter.parse(params).values(), OrderFile.class);
        Page<OrderFile> result = orderFileRepo.findAll(specification, pageable);
        return result;
    }

    @Override
    public OrderFile info(Long id) {
        return null;
    }

    /**
     * 判断目录是否存在
     * @param dirPath
     */
    private boolean isChartPathExist(String dirPath) {
        File file = new File(dirPath);
        return file.exists();
    }

    /**
     * 获取 jar包所在 目录路径
     *
     * @return
     */
    public String getPicSavePath ( ) {
        ApplicationHome home = new ApplicationHome(getClass());
        File jarFile = home.getSource();
        return jarFile.getParentFile().getParentFile().getAbsolutePath();
    }

    /**
     * 统一保存文件
     * @param request
     * @return
     */
    public String handleFileUpload(HttpServletRequest request) {
        String filePath = request.getParameter("savePath");
        String absolutePath = this.getPicSavePath() + spacer + filePath;
        if (this.isChartPathExist(absolutePath)){
            String result = FileUtil.saveFile(request, absolutePath + spacer);
            this.saveOnDb(request, filePath);
            return result;
        }
        return PATH_NO_EXIST;
    }


    /**
     * 保存文件到数据库
     * @param request 文件列表
     * @param filePath 文件目录
     */
    private void saveOnDb(HttpServletRequest request, String filePath) {
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        MultipartFile file = null;
        List<OrderFile> fileList = Lists.newArrayList();
        for (int i = 0; i < files.size(); ++i) {
            OrderFile orderFile = new OrderFile();
            orderFile.setDir(filePath);

            file = files.get(i);
            if (!file.isEmpty()) {
                orderFile.setFileName(file.getOriginalFilename());
            }
            fileList.add(orderFile);
        }
        orderFileRepo.saveAll(fileList);
    }

    /**
     * 下载文件
     * @param request
     * @param response
     * @return
     */
    public String download(HttpServletRequest request, HttpServletResponse response) {
        String fileName = request.getParameter("fileName");
        String filePath = request.getParameter("filePath");

        if (this.isChartPathExist(this.getPicSavePath() + spacer + filePath)){
            return this.downloadFile(fileName, filePath, response);
        }
        return PATH_NO_EXIST;
    }

    private String downloadFile(String fileName, String filePath, HttpServletResponse response) {
        if (fileName != null) {
            //设置文件路径
            File file = new File(getPicSavePath() + spacer + filePath + spacer + fileName);
            if (file.exists()) {
                response.setContentType("application/force-download");// 设置强制下载不打开
//                response.setContentType("application/OCTET-STREAM");
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                    return "下载成功";
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return "下载失败";
    }

    @Transactional
    public int deleteFile(String[] fileName, String filePath) {
        int sum = 0;
        for (int i = 0; i < fileName.length; ++i) {
            String name = fileName[i];
            if (name != null) {
                //设置文件路径
                File file = new File(getPicSavePath() + spacer + filePath + spacer + name);
                if (file.exists()) {
                    try {
                        file.delete();
                        int result = orderFileRepo.deleteByFileNameAndFilePath(name, filePath);
                        sum = result + sum;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return sum;
    }

    public String getOrderFileFlow(Order order, HttpServletResponse response) {
        String filePath = OPERATION_CONDITION_FORMAL;
        StringBuilder fileName = new StringBuilder();
        OrderFile orderFile = null;
        if (order != null){
            String orderId = order.getOrderId();
            String productCategory = order.getProductCategory();
            String purpose = order.getPurpose();
            if (!orderId.isEmpty() && !productCategory.isEmpty() && !purpose.isEmpty()){
                fileName.append(orderId.substring(1, 3) + "_");
                fileName.append(productCategory + "_");
                fileName.append(purpose);
                orderFile = orderFileRepo.getOrderFile(fileName.toString(), filePath);
            }
        }
        if (orderFile != null){
            try {
                this.readFile(response, orderFile.getFileName(), orderFile.getDir());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            return FILE_NO_EXIST;
        }
        return null;
    }

    public void readFile(HttpServletResponse res, String fileName, String filePath) throws Exception{
        InputStream in = null;
        OutputStream out = null;
        String newFilePath =  fileHandler(fileName, filePath);
        //判断是pdf还是word还是excel
        //若是pdf直接读 否则转pdf 再读  //
        try{
            if(newFilePath != null){
                in = new FileInputStream(newFilePath);
            }
            res.setContentType("application/pdf");
            out = res.getOutputStream();
            byte[] b = new byte[1024];
            int len = 0;
            while((len = in.read(b)) != -1){
                out.write(b);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(in != null){
                in.close();
            }
            if(out != null){
                out.close();
            }
        }
    }

    /**
     * 文件处理
     *
     * @param filePath
     * @param fileName
     * @return
     */
    public String fileHandler(String fileName, String filePath){
        String fileSuffix = FileUtil.getFileSuffix(fileName);
        System.out.println(fileSuffix);
        if("pdf".equals(fileSuffix))
        {
            return getPicSavePath() + spacer + filePath + spacer + fileName;
        }
        else
        {
            return Office2PDF.openOfficeToPDF(getPicSavePath() + spacer + filePath + spacer + fileName, filePath).getAbsolutePath();
        }

    }

    public String getFileFlow(HttpServletRequest request, HttpServletResponse response) {
        String fileName = request.getParameter("fileName");
        String filePath = request.getParameter("filePath");
        if (this.isChartPathExist(this.getPicSavePath() + spacer + filePath)){

        }else{
            return PATH_NO_EXIST;
        }
        OrderFile orderFile = orderFileRepo.getOrderFile(fileName, filePath);
        if (orderFile != null){
            try {
                this.readFile(response, fileName, filePath);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            return FILE_NO_EXIST;
        }
        return null;
    }
}
